<template>
  <a-form ref="form" class="standard-table-con h100" :model="fromData">
    <div class="fixed-con h100 edit-form-table">
      <div class="table-con h100 flex-column">
        <select-box
          v-show="showCheckedBoxCom"
          :select-num="nowSelectedKeys.length"
          @cancel-select="cancelSelect"
        ></select-box>
        <a-table
          v-model:selectedKeys="nowSelectedKeys"
          :data="fromData.tableData"
          bordered
          v-bind="$attrs"
          class="h100 flex-1"
          :class="!showPagination ? 'no-page' : ''"
          :style="{
            height: showCheckedBoxCom ? 'calc(100% - 100px)' : null,
          }"
          :row-selection="rowSelection"
          :pagination="showPagination ? pagination : false"
          @row-dblclick="dbClick"
          @page-change="pageChange"
          @page-size-change="pageSizeChange"
          @selection-change="selectionChange"
        >
          <template #empty>
            <div class="table-empty">
              <tableEmpty />
              <div class="empty-description">暂无数据</div>
            </div>
          </template>
          <template #columns>
            <template v-for="item in props.columns" :key="item.title">
              <a-table-column
                v-if="item.hasOwnProperty('children')"
                header-cell-class="edit-table-header"
                :title="item.title"
                :width="item.width"
                :ellipsis="true"
                :tooltip="true"
              >
                <a-table-column
                  v-for="child in item?.children"
                  :key="child.title"
                  header-cell-class="edit-table-header"
                  :title="child.title"
                  :ellipsis="true"
                  :tooltip="true"
                  :width="child?.width"
                >
                  <template #cell="{ record }">
                    <span>{{
                      record[child.dataIndex] === 0
                        ? record[child.dataIndex]
                        : record[child.dataIndex]
                        ? record[child.dataIndex]
                        : '-'
                    }}</span>
                  </template>
                </a-table-column>
              </a-table-column>
              <template v-else>
                <a-table-column
                  v-if="item.dataIndex === 'index'"
                  header-cell-class="edit-table-header"
                  :width="item.width"
                  :title="item.title"
                >
                  <template #cell="{ rowIndex }">
                    {{ rowIndex + 1 }}
                  </template>
                </a-table-column>
                <a-table-column
                  v-else-if="
                    item.dataIndex === 'secretLevel' && !secretLevelSelect
                  "
                  header-cell-class="edit-table-header"
                  :width="item.width"
                  :title="item.title"
                >
                  <template #cell="{ rowIndex, record }">
                    <secretLevel
                      :key="rowIndex"
                      :record="record"
                      v-bind="item.componentProps"
                    />
                  </template>
                </a-table-column>
                <a-table-column
                  v-else-if="item.dataIndex === 'operation'"
                  :title="item.title"
                  header-cell-class="edit-table-header edit-operation"
                  body-cell-class="edit-operation"
                  :width="item?.width"
                  :fixed="item.fixed"
                >
                  <template #cell="{ record, rowIndex, column }">
                    <slot
                      name="operation"
                      v-bind="{
                        rowIndex: rowIndex,
                        record: record,
                        column: column,
                      }"
                    ></slot>
                  </template>
                </a-table-column>
                <a-table-column
                  v-else-if="item.slotName"
                  :title="item.title"
                  header-cell-class="edit-table-header"
                  :width="item?.width"
                  :ellipsis="true"
                  :tooltip="true"
                >
                  <template
                    v-if="props.rules.hasOwnProperty(item.dataIndex)"
                    #title
                  >
                    <span>{{ item.title }}</span>
                    <span style="color: red"> *</span>
                  </template>
                  <template
                    v-if="props.rules.hasOwnProperty(item.dataIndex)"
                    #cell="{ record, rowIndex, column }"
                  >
                    <a-form-item
                      v-if="record.edit"
                      :field="`tableData.${rowIndex}.${item.dataIndex}`"
                      hide-label
                      :rules="props.rules[item.dataIndex]"
                      :validate-trigger="['change', 'blur']"
                    >
                      <slot
                        :name="[item.dataIndex]"
                        v-bind="{
                          rowIndex: rowIndex,
                          record: record,
                          column: column,
                        }"
                      ></slot>
                    </a-form-item>
                    <template v-else>
                      <slot
                        :name="[item.dataIndex]"
                        v-bind="{
                          rowIndex: rowIndex,
                          record: record,
                          column: column,
                        }"
                      ></slot>
                    </template>
                  </template>
                  <template v-else #cell="{ record, rowIndex, column }">
                    <slot
                      :name="[item.dataIndex]"
                      v-bind="{
                        rowIndex: rowIndex,
                        record: record,
                        column: column,
                      }"
                    ></slot>
                  </template>
                </a-table-column>
                <a-table-column
                  v-else
                  :title="item.title"
                  :ellipsis="true"
                  :tooltip="true"
                  header-cell-class="edit-table-header"
                  :width="item?.width"
                >
                  <template #cell="{ record }">
                    <span>{{
                      record[item.dataIndex] === 0
                        ? record[item.dataIndex]
                        : record[item.dataIndex]
                        ? record[item.dataIndex]
                        : '-'
                    }}</span>
                  </template>
                </a-table-column>
              </template>
            </template>
          </template>
          <template v-if="props.showAdd" #footer>
            <div class="footer-box">
              <span class="add-btn" @click="props.add()">
                <icon-plus style="margin-right: 6px" />
                添加</span
              >
            </div>
          </template>
        </a-table>
      </div>
    </div>
  </a-form>
</template>

<script setup lang="ts">
  import { watch, ref, reactive, PropType, computed } from 'vue';
  import secretLevel from '@/common/components/secret-level-info/index.vue';
  import usePagination from '@/common/hooks/pagination';
  import tableEmpty from '@/common/components/image/tableEmpty.svg?component';
  import lodash from 'lodash';
  import selectBox from '@/common/components/standard-table/selectBox.vue';

  type RowSelectionType = 'checkbox' | 'radio' | undefined;
  const props = defineProps({
    tableData: {
      type: Array,
      default: () => [],
    },
    columns: {
      type: Array as PropType<Array<Column>>,
      default: () => [],
    },
    rules: {
      type: Object,
      default: () => {
        return {};
      },
    },
    showAdd: {
      type: Boolean,
      default: true,
    },
    add: {
      type: Function,
      default() {
        return null;
      },
    },
    showPagination: {
      type: Boolean,
      default: false,
    },
    secretLevelSelect: {
      type: Boolean,
      default: false,
    },
    total: {
      type: Number,
      default: 0,
    },
    showCheckedBox: {
      type: Boolean,
      default: true,
    },
    selectedKeys: {
      type: Array,
      default: () => [],
    },
    rowSelection: {
      type: String as PropType<RowSelectionType>,
      default: '',
    },
  });
  const { pagination, setCurrent, setPageSize, setTotal, queryPagination } =
    usePagination();

  const emit = defineEmits([
    'update:selectedKeys',
    'rowDblclick',
    'pageSizeChange',
    'selectionChange',
    'pageChange',
  ]);
  interface Column {
    width?: number | undefined;
    title: string;
    dataIndex: string;
    slotName?: string;
    fixed?: undefined | 'left' | 'right';
    tooltip?: boolean;
    ellipsis?: boolean;
    componentProps?: object;
    children?: Array<Column>;
  }
  interface DataItem {
    id: number | string;
    edit: boolean;
  }
  const nowSelectedKeys: any = ref(props.selectedKeys);
  watch(
    () => props.selectedKeys,
    () => {
      nowSelectedKeys.value = props.selectedKeys;
    }
  );
  const form = ref<any>();
  const fromData = reactive({
    tableData: [] as Array<DataItem>[],
  });
  const showCheckedBoxCom = computed(() => {
    if (!props.showCheckedBox) {
      return false;
    }
    if (props.rowSelection !== 'checkbox') {
      return false;
    }
    if (nowSelectedKeys.value && nowSelectedKeys.value.length) {
      return true;
    }
    return false;
  });
  const cancelSelect = () => {
    nowSelectedKeys.value = [];
    selectionChange([]);
  };
  const selectionChange = (val: string[]) => {
    emit('update:selectedKeys', val);
    emit('selectionChange', val);
  };
  watch(
    () => props.tableData,
    (n: any) => {
      fromData.tableData = [];
      if (n && n.length > 0) {
        fromData.tableData.push(...n);
      }
    },
    {
      immediate: true,
      deep: true,
    }
  );
  watch(
    () => props.total,
    () => {
      setTotal(props.total);
    }
  );
  const dbClick = (record: any) => {
    emit('rowDblclick', record);
  };
  const query = computed(() => {
    return lodash.cloneDeep(queryPagination.value);
  });
  const pageChange = (val: number) => {
    setCurrent(val);
    emit('pageChange', lodash.cloneDeep(queryPagination.value));
  };
  const getStatus = () => {
    return {
      ...queryPagination.value,
    };
  };
  const pageSizeChange = (val: number) => {
    setPageSize(val);
    emit('pageSizeChange', lodash.cloneDeep(queryPagination.value));
  };
  // 表单校验
  const formCheck = () => {
    return form.value.validate();
  };
  // 表单校验
  const formCheckField = async (index: any, field: any) => {
    form.value.validateField(`tableData.${index}.${field}`);
  };
  defineExpose({
    query,
    formCheck,
    getStatus,
    setCurrent,
    formCheckField,
    fromData,
  });
</script>

<style lang="less" scoped>
  @import url('../common.less');
  .standard-table-con {
    background: #fff;
    border-radius: 8px;
    :deep(.arco-table-pagination) {
      margin-top: 0px;
      padding-top: 16px;
      background-color: #fff !important;
    }
  }
  .fixed-con {
    display: flex;
    flex-direction: row;
    width: 100%;
  }
  .table-con {
    flex: 1;
    width: 1px;
  }
  .footer-box {
    text-align: center;
    .add-btn {
      cursor: pointer;
    }
  }
</style>

<style lang="less">
  .no-page.edit-table {
    .arco-table-pagination {
      display: none;
    }
  }

  .edit-form-table {
    display: flex;
    flex-direction: column;

    .arco-spin {
      display: flex;
      flex-direction: column;
      flex: 1;
      .arco-table-container {
        flex: 1;
      }
    }
    .table-empty {
      box-sizing: border-box;
      width: 100%;
      padding: 10px 0;
      text-align: center;
    }
    .empty-description {
      color: rgb(var(--gray-5));
      font-size: 14px;
    }
    .arco-table-th.edit-table-header {
      .arco-table-cell.arco-table-cell-align-left {
        border-right: 1px solid #e4e7ed;
      }
    }
    .arco-table-th.arco-table-col-fixed-right.edit-table-header.edit-operation {
      border-left: 1px solid #e4e7ed;
      box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
        0px 4px 5px 0px rgba(0, 0, 0, 0.08),
        0px 1px 10px 0px rgba(0, 0, 0, 0.05);
    }
    .arco-table-td .arco-table-cell.arco-table-cell-align-left {
      .arco-form-item {
        margin-bottom: 0px;
      }
    }
    .arco-table-td.arco-table-col-fixed-right {
      .arco-table-cell.arco-table-cell-align-left {
        padding: 0px;
      }
      border-left: 1px solid #e4e7ed;
      box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
        0px 4px 5px 0px rgba(0, 0, 0, 0.08),
        0px 1px 10px 0px rgba(0, 0, 0, 0.05);
    }
    .arco-table-td.edit-operation {
      .arco-table-cell {
        padding: 0px;
      }
    }
  }
</style>
